//
//  NSMutableArray+BPCrash.m
//  BPCrashDemo
//
//  Created by SiYugui on 2019/12/18.
//  Copyright © 2019年 SiYugui. All rights reserved.
//

#import "NSMutableArray+BPCrash.h"
#import "BPCrashLog.h"
#import "NSObject+BPSwizzle.h"

@implementation NSMutableArray (BPCrash)

+(void)avoidMutableArrayCrashExchangeMethod{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        Class __ArrayM = NSClassFromString(@"__NSArrayM");
        
        //objectAtIndex:
        [BPCrashLog exchangeInstanceMethod:__ArrayM method1:@selector(objectAtIndex:) method2:@selector(__ObjectAtIndex:)];
        
        //objectAtIndexedSubscript:
        if (@available(iOS 11.0, *)) {
            [self exchangeInstanceMethod:__ArrayM method1:@selector(objectAtIndexedSubscript:) method2:@selector(__objectAtIndexedSubscript:)];
        }
        
        //setObject:atIndexedSubscript:
        [self exchangeInstanceMethod:__ArrayM method1:@selector(setObject:atIndexedSubscript:) method2:@selector(__setObject:atIndexedSubscript:)];
    
        //removeObjectAtIndex:
        [self exchangeInstanceMethod:__ArrayM method1:@selector(removeObjectAtIndex:) method2:@selector(removeObjectAtIndex:)];
        
        //insertObject:atIndex:
        [self exchangeInstanceMethod:__ArrayM method1:@selector(insertObject:atIndex:) method2:@selector(__insertObject:atIndex:)];
        
        //getObjects:range:
        [self exchangeInstanceMethod:__ArrayM method1:@selector(getObjects:range:) method2:@selector(__getObjects:range:)];
    });
}

#pragma mark - objectAtIndex:

- (id)__ObjectAtIndex:(NSUInteger)index {
    id object = nil;
    
    @try {
        object = [self __ObjectAtIndex:index];
    }
    @catch (NSException *exception) {
        NSString *defaultToDo = BPCrashDefaultReturnNil;
        [BPCrashLog noteErrorWithException:exception attachedToDo:defaultToDo];
    }
    @finally {
        return object;
    }
}

#pragma mark - objectAtIndexedSubscript:

-(id)__objectAtIndexedSubscript:(NSUInteger)idx{
    id object = nil;
    
    @try {
        object = [self __objectAtIndexedSubscript:idx];
    }
    @catch (NSException *exception) {
        NSString *defaultToDo = BPCrashDefaultReturnNil;
        [BPCrashLog noteErrorWithException:exception attachedToDo:defaultToDo];
    }
    @finally {
        return object;
    }
}

#pragma mark - setObject:atIndexedSubscript:
-(void)__setObject:(id)obj atIndexedSubscript:(NSUInteger)idx{
    @try {
        [self __setObject:obj atIndexedSubscript:idx];
    }
    @catch (NSException *exception) {
        [BPCrashLog noteErrorWithException:exception attachedToDo:BPCrashDefaultReturnIgnore];
    }
    @finally {
        
    }
}

#pragma mark - removeObjectAtIndex:
-(void)__removeObjectAtIndex:(NSUInteger)index{
    @try {
        [self __removeObjectAtIndex:index];
    }
    @catch (NSException *exception) {
        [BPCrashLog noteErrorWithException:exception attachedToDo:BPCrashDefaultReturnIgnore];
    }
    @finally {
        
    }
}

#pragma mark - insertObject:atIndex:

-(void)__insertObject:(id)anObject atIndex:(NSUInteger)index{
    @try {
        [self __insertObject:anObject atIndex:index];
    }
    @catch (NSException *exception) {
        [BPCrashLog noteErrorWithException:exception attachedToDo:BPCrashDefaultReturnIgnore];
    }
    @finally {
        
    }
}

#pragma mark - getObjects:range:

-(void)__getObjects:(__unsafe_unretained id  _Nonnull [])objects range:(NSRange)range{
    @try {
        [self __getObjects:objects range:range];
    } @catch (NSException *exception) {
        [BPCrashLog noteErrorWithException:exception attachedToDo:BPCrashDefaultReturnIgnore];
    } @finally {
        
    }
}
@end
